<template>
  <div class="box-container">
    <!-- 工具栏 -->
    <div class="toolbar">
      <el-input v-model="searchKey" placeholder="搜索文章" style="width: 300px" clearable />
      <el-button type="primary" @click="handleAdd" class="ml-2">
        <i class="ri-add-line"></i>新增文章
      </el-button>
    </div>

    <!-- 数据表格 -->
    <el-table :data="articles" border fit highlight-current-row>
      <el-table-column prop="title" label="标题" />
      <el-table-column prop="type" label="栏目" />
      <el-table-column prop="tags" label="标签"/>
      <el-table-column prop="author" label="作者" />
      <el-table-column prop="createDate" label="创建时间" />
      <el-table-column prop="updateDate" label="更新时间" />
      <el-table-column label="操作" >
        <template #default="scope">
          <el-button size="small" @click="handleEdit(scope.row)">编辑</el-button>
          <el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <div class="pagination">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[10, 20, 50]"
        layout="total, sizes, prev, pager, next"
        :total="articles.length"
      />
    </div>

    <el-dialog v-model="dialog.visible" :title="dialog.title" width="800" @closed="resetDialog">
      <el-form v-model="dialog.form" label-width="120" label-position="top">
        <el-form-item label="文章标题">
          <el-input v-model="dialog.form.title" placeholder="请输入文章标题"></el-input>
        </el-form-item>
        <el-form-item label="文章封面">
          <div class="img-selector-container">
            <div v-if="dialog.imgUrl" class="cover-container">
              <el-image fit="fill" :src="dialog.imgUrl" alt="封面" />
              <el-button 
                class="delete-cover-btn"
                type="danger" 
                icon="ri-delete-bin-line"
                circle
                @click="handleDeleteCover">
                <i class="ri-close-large-line"></i>
              </el-button>
            </div>
            <el-upload
              v-else
              ref="uploadImgRef"
              :drag="true"
              accept=".png,.mbp,.jpg,.jpeg,.gif,.webp"
              :limit="1"
              :auto-upload="false"
              :on-change="handleImgChange"
              :on-remove="handleImgRemove"
              dialog.value.imgUrl>
              <div v-if="dialog.imgUrl">
                <img :src="dialog.imgUrl" alt="">
              </div>
              <div v-else>
                <div>
                  <i class="ri-upload-cloud-line"></i>
                </div>
                <em>click to upload</em>
              </div>
            </el-upload>
          </div>
        </el-form-item>
        <el-form-item label="文章简介">
          <el-input type="textarea" :rows="3" placeholder="请输入文章简介" v-model="dialog.form.description"></el-input>
        </el-form-item>
        <el-form-item label="选择分栏">
          <el-select
            v-model="dialog.form.type"
            placeholder="选择分栏"
            clearable
            allow-create>
            <el-option v-for="item in typeList" :key="item.id" :value="item.name" :label="item.name"></el-option>
            <template #footer>
              <el-button v-if="!dialog.option.isAdding" text bg size="small" @click="addOption">
                Add an option
              </el-button>
              <template v-else>
                <el-input v-model="dialog.option.name"
                  placeholder="input option name"
                />
                <el-button type="primary" size="small" @click="onAddOption">
                  确认
                </el-button>
                <el-button size="small" @click="cancleAddOption">取消</el-button>
              </template>
            </template>
          </el-select>
        </el-form-item>
        <el-form-item label="文章标签">
          <el-input-tag v-model="dialog.form.tagList" trigger="Enter" placeholder="请输入标签"></el-input-tag>
        </el-form-item>
        <el-form-item label="文章链接" v-if="dialog.form.url">
          <el-input  v-model="dialog.form.url" disabled />
        </el-form-item>
        <el-form-item lable="选择文件" v-else>
          <el-upload
            ref="uploadFileRef"
            accept=".md"
            :auto-upload="false"
            :on-change="handleFileChange"
            :on-remove="handleFileRemove"
            :limit="1">
            <template #trigger>
              <el-button type="primary"><i class="ri-file-upload-line"></i>选择文件</el-button>
            </template>
          </el-upload>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button color="#197278" @click="handleArticleAddEdit">{{ dialog.type === 'add' ? '发布文章' : '确认修改 ' }}</el-button>
        <el-button type="primary" @click="handleView" v-if="dialog.type === 'edit'">查看文章</el-button>
        <el-button color="#edddd4" @click="handleCancle">取消</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { addArticle, getArticleList, deleteArticle, updateArticle, 
  getAllTypeList, addType, uploadFile, deleteFile } from  '@/api/article.js';
import { ElMessage, ElMessageBox } from 'element-plus';
import useLoginState from '@/stores/userinfo';

const loginState = useLoginState();
const typeList = ref([]);
const dialog = ref({
  visible: false,
  title: '新增文章',
  content: '',
  type: 'add', // add, edit
  form: { },
  imgUrl: '',
  option: {
    updateDate: '',
    isAdding: false,
    name: ''
  },
})
// 搜索关键词
const searchKey = ref('')

// tables data
const articles = ref([])
const currentPage = ref(1)
const pageSize = ref(10)
const total = ref(0)

const getDatList = function() {
  getArticleList(currentPage.value, pageSize.value, {}).then(resp => {
    if (resp.code === 200) {
      articles.value = resp.rows;
      total.value = resp.total;
      return;
    }
    if (resp.code === 500) {
      ElMessage.error(resp.msg);
      return;
    }
  })
}
const getTypeListDat = function() {
  getAllTypeList().then(resp => {
    if (resp.code === 200) {
      typeList.value = resp.data;
      return;
    }
    if (resp.code === 500) {
      ElMessage.error(resp.msg);
      return;
    }
  })
}

onMounted(() => {
  dialog.value.form.author = loginState.username;
  getDatList();
  getTypeListDat();
})

// 操作处理
const handleAdd = () => {
  dialog.value.visible = true
  dialog.value.type = 'add';
  dialog.value.title = '新增文章';
}
const handleEdit = (row) => {
  dialog.value.visible = true
  dialog.value.type = 'edit';
  dialog.value.title = '修改文章';
  dialog.value.form = row;
  dialog.value.form.tagList = row.tags.split(',');
  dialog.value.imgUrl = row.imageUrl;
}
const handleDelete = (row) => {
  ElMessageBox.confirm('确定删除该文章吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    // 删除文章
    deleteArticle(row.id).then(resp => {
      if (resp.code === 200) {
        getDatList();
        ElMessage({message: resp.msg, type: 'success'});
        return;
      }
      ElMessage.error(resp.msg);
    })
  }).catch(() => {
    // 取消删除
  })
}

// Image upload
const uploadImgRef = ref(null);
const selectImage = ref(null);
const handleImgChange = function(file) {
  console.log('change image: ', file);
  selectImage.value = file.raw;
  dialog.value.imgUrl = URL.createObjectURL(file.raw);
}
const handleImgRemove = function() {
  selectImage.value = null;
  dialog.value.imgUrl = '';
}

// Article upload
const uploadFileRef = ref(null);
const selectedFile = ref(null);
const doAddArticle = function() {
  const dat = {
    title: dialog.value.form.title,
    description: dialog.value.form.description,
    author: loginState.username,
    type: dialog.value.form.type,
    tags: dialog.value.form.tagList.join(','),
    imageUrl: dialog.value.form.imageUrl,
    url: dialog.value.form.url, // 文章链接
  }
  addArticle(dat).then(resp => {
    if (resp.code === 500) {
      ElMessage.error(resp.msg);
      return;
    }
    if (resp.code === 200) {
      getDatList();
      ElMessage({message: resp.msg, type: 'success'});
      dialog.value.visible = false;
      return;
    }
  })
}
const doUpdateArticle = function() {
  const dat = {
    id: dialog.value.form.id,
    title: dialog.value.form.title,
    description: dialog.value.form.description,
    type: dialog.value.form.type,
    tags: dialog.value.form.tagList.join(','),
    imageUrl: dialog.value.form.imageUrl,
  }
  updateArticle(dat).then(resp => {
    if (resp.code === 500) {
        ElMessage.error(resp.msg);
        return;
      }
      if (resp.code === 200) {
        getDatList();
        ElMessage({message: resp.msg, type: 'success'});
        dialog.value.visible = false;
        return;
      }
  })
}
const handleArticleAddEdit = function() {
  if (dialog.value.type === 'add') {
    if (!selectedFile.value) {
      ElMessage.error('请选择文章');
      return;
    }
    const fileForm = new FormData();
    fileForm.append('file', selectedFile.value);
    fileForm.append('type', 'blog');
    // upload article
    uploadFile(fileForm).then(resp => {
      if (resp.code === 500) {
        ElMessage.error(resp.msg);
        return;
      }
      dialog.value.form.url = resp.data;
      // upload image
      if (selectImage.value) {
        const imgForm = new FormData();
        imgForm.append('file', selectImage.value);
        imgForm.append('type', 'image');
        uploadFile(imgForm).then(resp => {
          if (resp.code === 500) {
            ElMessage.error(resp.msg);
            return;
          }
          if (resp.code === 200) {
            dialog.value.form.imageUrl = resp.data;
            doAddArticle();
          }
        })
      } else {
        doAddArticle();
      }
    })
  } 
  // update article
  else {
    if (selectImage.value) {
      const imgForm = new FormData();
      imgForm.append('file', selectImage.value);
      imgForm.append('type', 'image');
      uploadFile(imgForm).then(resp => {
        if (resp.code === 500) {
          ElMessage.error(resp.msg);
          return;
        }
        if (resp.code === 200) {
          dialog.value.form.imageUrl = resp.data;
          doUpdateArticle(resp.data);
        }
      })
    } else {
      doUpdateArticle();
    }
  }
}
const handleFileChange = function(file) {
  selectedFile.value = file.raw;
  if (!dialog.value.form.title) {
    const fiename = file.name;
    dialog.value.form.title = fiename.substring(0, fiename.lastIndexOf('.'));
  }
}
const handleFileRemove = function() {
  selectedFile.value = null;
}

// add option
const addOption = function() {
  dialog.value.option.isAdding = true;
}
const onAddOption = function() {
  const optionName = dialog.value.option.name;
  if (optionName) {
    addType({name: optionName, author: loginState.username}).then(resp => {
      if (resp.code === 500) {
        ElMessage.error(resp.msg);
        return;
      }
      if (resp.code === 200) {
        getTypeListDat();
        dialog.value.option.isAdding = false;
        dialog.value.option.name = '';
      }
    })
  }
}
const cancleAddOption = function() {
  dialog.value.option.isAdding = false;
  dialog.value.option.name = '';
}

const resetDialog = function() {
  dialog.value.form = {};
  dialog.value.visible = false;
  dialog.value.imgUrl = '';
  selectImage.value = null;
  uploadImgRef.value?.clearFiles();
}
const handleCancle = function() {
  dialog.value.visible = false;
}

const handleView = function() {
  // TODO: 打开文章预览页面
}

const handleDeleteCover = () => {
  dialog.value.form.imageUrl = '';
  dialog.value.imgUrl = '';
}
</script>

<style scoped>
.toolbar {
  margin-bottom: 20px;
  display: flex;
  align-items: center;
}

.ml-2 {
  margin-left: 20px;
}

.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.el-table {
  margin-top: 20px;
  border-radius: 8px;
  overflow: hidden;
}

.el-button {
  padding: 8px 12px;
}

.img-selector-container {
  max-width: 150px;
  max-height: 150px;
}

.img-selector-container img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.cover-container {
  position: relative;
  display: inline-block;
}

.delete-cover-btn {
  opacity: 0;
  transition: opacity 0.2s ease-in-out, transform 0.2s ease;
  position: absolute;
  top: 8px;
  right: 8px;
  background-color: transparent !important;
  border: none;
  padding: 4px;
}

.cover-container:hover .delete-cover-btn {
  opacity: 1;
}

.delete-cover-btn :deep(.el-icon) {
  color: #ff4d4f;
  font-size: 18px;
}

.delete-cover-btn:hover :deep(.el-icon) {
  color: #ff7875;
}
.delete-cover-btn {
  width: 32px;
  height: 32px;
}
.delete-cover-btn:hover {
  transform: scale(1.1);
}
</style>
